package com.wxjfkg.workflow.impl;

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import com.fivestar.app.vo.AppConstants;
import com.fivestar.app.vo.AppMessageVO;
import com.fivestar.credit.service.vo.ApplyCredTakeProdDto;
import com.fivestar.credit.service.vo.CreditConstants;
import com.fivestar.customer.service.CustomerService;
import com.fivestar.customer.service.vo.CustomerDto;
import com.fivestar.util.date.DateTimeUtils;
import org.activiti.engine.delegate.DelegateExecution;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fivestar.account.enums.BusiCode;
import com.fivestar.account.enums.ResultCode;
import com.fivestar.account.service.AccountPlatformService;
import com.fivestar.appmsg.service.AppMsgService;
import com.fivestar.credit.service.ApplyCreditService;
import com.fivestar.credit.service.CreditLimitService;
import com.fivestar.credit.service.vo.ApplyCredTakeDto;
import com.fivestar.loan.service.ProductDefiService;
import com.fivestar.loan.service.vo.ApplyConstants;
import com.fivestar.loan.service.vo.ProdPriceFee;
import com.fivestar.loan.service.vo.ProductDefiVo;
import com.fivestar.loan.service.vo.ProductFeeDto;
import com.fivestar.loan.service.vo.ProductInteDto;
import com.fivestar.merchant.service.MerchantService;
import com.fivestar.merchant.service.vo.MerchantConstants;
import com.fivestar.merchant.service.vo.MerchantInfoDto;
import com.fivestar.meta.MetaData;
import com.fivestar.meta.MetaTree;
import com.fivestar.query.vo.ResultDto;
import com.fivestar.settlement.common.Constants;
import com.fivestar.settlement.common.ParamKeys;
import com.fivestar.util.meta.MetaTreeUtil;
import com.wxjfkg.workflow.BeforeEndTaskService;

@Service("applyTakeSuccessTaskServiceImpl")
public class ApplyTakeSuccessTaskServiceImpl implements BeforeEndTaskService {

	public Logger logger = LoggerFactory.getLogger(ApplyTakeSuccessTaskServiceImpl.class);

	@Autowired
	private ApplyCreditService applyCreditService;

	@Autowired
	private ProductDefiService productService;

	@Autowired
	private AccountPlatformService accountPlatformService;

	@Autowired
	private MerchantService merchantService;

	@Autowired
	private CustomerService customerService;

	@Autowired
	private CreditLimitService creditLimitService;
	
	@Autowired
	private AppMsgService appMsgService;

	@Value("${loanUseMsgContent}")
	private String loanUseMsgContent;

	@Override
	@Transactional(value = "txTranManager")
	public void execute(DelegateExecution execution) throws Exception {
		String businessKey = execution.getProcessBusinessKey();
		logger.info("用信编号{}", businessKey);
		// 调用账户系统生成放款信息
		if (StringUtils.isNotEmpty(businessKey)) {
			// 1.1:调用账户系统创建账户信息
			ApplyCredTakeDto applyDto = new ApplyCredTakeDto();
			applyDto.setApplyId(businessKey);
			ResultDto<ApplyCredTakeDto> resultDto = applyCreditService.queryApplyCreditDetail(applyDto);
			if (resultDto != null && resultDto.isSuccess() && resultDto.getData() != null) {
				ApplyCredTakeDto applyTake = resultDto.getData();
				// 申请信息
				MetaData data = new MetaData();
				data.set(ParamKeys.TRAN_TYPE, Constants.TRAN_TYPE_CREDIT);
				data.set(ParamKeys.BUSI_TYPE, Constants.BUSI_TYPE_LOANS_BUSINESS);
				data.set(ParamKeys.APPLY_ID, applyTake.getApplyId());
				//todo
				data.set("userType", MerchantConstants.MERCH_LEVEL.ZHS);
				//店铺
				if(StringUtils.isNotEmpty(applyTake.getMerchId())) {
					MerchantInfoDto merchantInfo = new MerchantInfoDto();
					merchantInfo.setMerchId(applyTake.getMerchId());
					List<MerchantInfoDto> merchantInfoList = merchantService.qryMerchantList(merchantInfo);
					if (merchantInfoList != null && !merchantInfoList.isEmpty()) {
						merchantInfo = merchantInfoList.get(0);
						data.set(ParamKeys.USER_ID, applyTake.getMerchId());
						data.set("custId", applyTake.getMerchId());
						data.set(ParamKeys.CUST_NAME, merchantInfo.getMerchRelatedName());
						data.set(ParamKeys.CERT_TYPE, "0");
						data.set(ParamKeys.CERT_ID, merchantInfo.getShopOwnerIdNum());
						//todo
						data.set(ParamKeys.MERCH_ID, applyTake.getMerchId());
						data.set(ParamKeys.APPLY_MOBILE, merchantInfo.getMerchRelatedMobile());
						data.set(ParamKeys.APPLY_NAME, merchantInfo.getMerchRelatedName());
					}
				}
				//个人
				else if(StringUtils.isNotEmpty(applyTake.getCustId())) {
					CustomerDto customerDto = new CustomerDto();
					customerDto.setCustId(applyTake.getCustId());
					List<CustomerDto> customerDtoList = customerService.qryCustomerList(customerDto);
					if(customerDtoList != null && !customerDtoList.isEmpty()) {
						customerDto = customerDtoList.get(0);
						data.set(ParamKeys.USER_ID, applyTake.getCustId());
						data.set("custId", applyTake.getCustId());
						data.set(ParamKeys.CUST_NAME, customerDto.getCustName());
						data.set(ParamKeys.CERT_TYPE, "0");
						data.set(ParamKeys.CERT_ID, customerDto.getIdCard());
						//todo
						data.set(ParamKeys.MERCH_ID, applyTake.getMerchId());
						data.set(ParamKeys.APPLY_MOBILE, customerDto.getMobile());
						data.set(ParamKeys.APPLY_NAME, customerDto.getCustName());
					}
				}
				// 授信编号和合同编号
				data.set("currSign", "CNY");
				data.set("loanTerm", applyTake.getLoanTerm());
				data.set("loanTermUnit", applyTake.getLoanTermUnit());
				data.set(ParamKeys.LOAN_BEGIN_DATE, applyTake.getLoanBeginDate());
				data.set(ParamKeys.LOAN_END_DATE, applyTake.getLoanEndDate());
				data.set(ParamKeys.LOAN_RETU_TERM, applyTake.getLoanRetuTerm());
				data.set(ParamKeys.REPAY_KIND, applyTake.getRepayKind());

				// 账户信息
				data.set("payBankname", applyTake.getPayBankname());
				data.set("payBankid", applyTake.getPayBankid());
				data.set("payCustname", applyTake.getPayCustname());
				data.set("payAccno", applyTake.getPayAccno());
				data.set(ParamKeys.REPAY_ACCNO, StringUtils.isEmpty(applyTake.getRepayAccno()) ? applyTake.getPayAccno() : applyTake.getRepayAccno());
				data.set(ParamKeys.REPAY_ACCNAME, StringUtils.isEmpty(applyTake.getRepayAccname()) ? applyTake.getPayCustname() : applyTake.getRepayAccname());
				//该用信申请包含的贷款产品定义信息、费用信息及利率信息
				List<ApplyCredTakeProdDto> prods = applyTake.getProds();
				//分产品多次调用账务平台分布生成放款记录
				for(ApplyCredTakeProdDto prod : prods) {
					data.set("prodId", prod.getProdId());
					data.set("creditType", prod.getCreditType());
					data.set(ParamKeys.LOAN_AMT, prod.getLoanAmt());
					data.set(ParamKeys.GRACE_DAY, prod.getGraceDay());
					data.set("delayDay", prod.getDelayDay());
					ProductDefiVo product = new ProductDefiVo();
					product.setProdId(prod.getProdId());
					// 获取产品定义信息
					List<ProductDefiVo> products = productService.selectProductDefiInfo(product);
					if (products != null && !products.isEmpty()) {
						product = products.get(0);
						// 还款日约定
						data.set(ParamKeys.RETUDAY_KIND, product.getRetudayKind());
						data.set(ParamKeys.FIRST_RETUDAY_KIND, product.getFirstRetudayKind());
						// 产品定义还款日
						data.set(ParamKeys.PROD_RETU_DAY, product.getRetuday());
						// 产品归属类型
						data.set(ParamKeys.PROD_OWNER_TYPE, product.getProdOwnerType());
						// 放款是否资金管控
						data.set(ParamKeys.PROD_FUND_CTRL, product.getProdFundCtrl());
						// 扣款方式(1-系统代扣 2-主动还款)
						data.set(ParamKeys.DEDUCT_KIND, product.getDeductKind());
					}
					else {
						logger.error("未查询到用信申请产品定义信息{}", prod.getProdId());
					}
					// 获取产品费用信息
					ProductFeeDto productFee = new ProductFeeDto();
					productFee.setProdId(prod.getProdId());
					productFee.setApplyAmt(String.valueOf(prod.getLoanAmt()));
					productFee.setApplyTerm(String.valueOf(applyTake.getLoanTerm()));
					List<ProdPriceFee> fees = productService.selectProductFeeList(productFee);
					List<MetaData> feeMapList = new ArrayList<MetaData>();
					if (fees != null && !fees.isEmpty()) {
						for (ProdPriceFee fee : fees) {
							MetaData item = new MetaData();
							item.set(ParamKeys.FEE_DEFI_KIND, fee.getFeeDefiKind());
							item.set(ParamKeys.RETU_FEE_KIND, fee.getRetuFeeKind());
							item.set(ParamKeys.FEE_FIX_AMT, fee.getFixedAmount());
							item.set(ParamKeys.FEE_RATE, fee.getFeeRate());
							item.set(ParamKeys.FEE_MIN, fee.getFeeMin());
							item.set(ParamKeys.FEE_MAX, fee.getFeeMax());
							item.set(ParamKeys.FEE_COMPBASE, fee.getFeeCompbase());
							item.set(fee.getFeeCompbase(), prod.getLoanAmt()); // 基数就是金额
							feeMapList.add(item);
						}
					}
					data.set(ParamKeys.FEE_INFO, feeMapList);

					// 获取产品利率信息
					List<ProductInteDto> intes = productService.selectProductInteList(productFee);
					if (intes != null && !intes.isEmpty()) {
						ProductInteDto inte = intes.get(0);
						data.set(ParamKeys.LOAN_INTERATE, inte.getLoanInte());
						data.set(ParamKeys.INTE_TYPE, inte.getInteType());
					}
					else {
						logger.info("未设置产品利率信息{}", prod.getProdId());
						data.set(ParamKeys.LOAN_INTERATE, BigDecimal.ZERO);
						data.set(ParamKeys.INTE_TYPE, "M");//默认月利率
					}

					// 贷款产品设置的一次性费用信息
					List<ProdPriceFee> feeOnces = productService.selectProductFeeOnceList(productFee);
					List<MetaData> mapList = new ArrayList<MetaData>();
					for (ProdPriceFee ppf : feeOnces) {
						// 一次性手续费
						MetaData item = new MetaData();
						item.set(ParamKeys.FEE_DEFI_KIND, ppf.getFeeDefiKind());
						item.set(ParamKeys.RETU_FEE_KIND, ppf.getRetuFeeKind());
						item.set(ParamKeys.FEE_FIX_AMT, ppf.getFixedAmount());
						item.set(ParamKeys.FEE_RATE, ppf.getFeeRate());
						item.set(ParamKeys.FEE_MIN, ppf.getFeeMin());
						item.set(ParamKeys.FEE_MAX, ppf.getFeeMax());
						item.set(ParamKeys.FEE_COMPBASE, ppf.getFeeCompbase());
						item.set(ppf.getFeeCompbase(), prod.getLoanAmt()); // 基数就是金额
						mapList.add(item);
					}
					data.set(ParamKeys.FEE_INFO_ONCE, mapList);

					data.set(ParamKeys.RETUDAY_KIND, product.getRetudayKind());
					data.set(ParamKeys.LOAN_BEGIN_DATE, applyTake.getLoanBeginDate());
					data.set(ParamKeys.LOAN_RETU_TERM, applyTake.getLoanTerm());
					data.set(ParamKeys.PROD_RETU_DAY, product.getRetuday());
				}

				logger.info("requestMap" + data);
				MetaTree metaTree = MetaTreeUtil.setRequsetByBusiCode(BusiCode.LOAN.getBusiCod(), data.getMap());
				metaTree = accountPlatformService.doService(metaTree);
				if (!ResultCode.SUCC.getResultCode().equals(metaTree.getResult().getString(MetaTreeUtil.RETURN_CODE))) {
					logger.error("调用账户信息失败");
					throw new RuntimeException(metaTree.getResult().getString(MetaTreeUtil.RETURN_DESC));
				}
				else {
					// 1.2:額度信息
					logger.info("调用账户信息成功");
					// 1.3更新用信申请放款信息
					ApplyCredTakeDto apply = new ApplyCredTakeDto();
					apply.setAppStat(ApplyConstants.DiscountStatusEnum.LOAN_SUCCESS.getStatusCode());
					apply.setApplyId(applyTake.getApplyId());
					apply.setLoanAmt(applyTake.getApplyAmt());
					apply.setApprAmt(applyTake.getApplyAmt());
					applyCreditService.mergeApplyCredStat(apply);
				}
				
				//1.3发送消息通知
				AppMessageVO messageVO = new AppMessageVO();
				messageVO.setMsgSubType(AppConstants.APP_MSG_SUBTYPE.WALLET);
				messageVO.setMsgTitle("贷款提醒");
		        //从催收内容模板生成催收内容
				String prodName = "";
				if(CreditConstants.CREDIT_USE_TYPE.JH.equals(applyTake.getLoanUse())){
					prodName = "进货";
				}else if(CreditConstants.CREDIT_USE_TYPE.NQ.equals(applyTake.getLoanUse())){
					prodName = "拿钱";
				}
				//申请用户名称
				String applicantName = null;
				//申请用户登录账号
				String applicantLoginId = null;
				//店铺
				if(StringUtils.isNotEmpty(applyTake.getMerchId())) {
					MerchantInfoDto merchantInfo = new MerchantInfoDto();
					merchantInfo.setMerchId(applyTake.getMerchId());
					List<MerchantInfoDto> merchantInfoList = merchantService.qryMerchantList(merchantInfo);
					if (merchantInfoList != null && !merchantInfoList.isEmpty()) {
						merchantInfo = merchantInfoList.get(0);
					}
					applicantName = merchantInfo.getMerchName();
					applicantLoginId = merchantInfo.getMerchRelatedMobile();
				}
				//个人
				else if(StringUtils.isNotEmpty(applyTake.getCustId())) {
					CustomerDto customerDto = new CustomerDto();
					customerDto.setCustId(applyTake.getCustId());
					List<CustomerDto> customerDtoList = customerService.qryCustomerList(customerDto);
					if(customerDtoList != null && !customerDtoList.isEmpty()) {
						customerDto = customerDtoList.get(0);
					}
					applicantName = customerDto.getCustName();
					//todo 待确认服务中心后台登录方式
					applicantLoginId = customerDto.getCustId();
				}
		        String content = MessageFormat.format(loanUseMsgContent,
						applicantName, businessKey.substring(businessKey.length() - 4), prodName, "已放款");
		        messageVO.setMsgContent(content);
		        messageVO.setContentSource(businessKey);
		        Date now = new Date();
		        //消息有效时间为提醒时间当天至次日
		        messageVO.setStartTime(now);
		        messageVO.setEndTime(DateTimeUtils.getUpdateDateTime(now, Calendar.DAY_OF_MONTH, 1));
		        messageVO.setLoginId(applicantLoginId);
				appMsgService.createXbtBusinessMsg(messageVO);
			}
			else {
				logger.error("未查询到用信申请信息{}", businessKey);
			}
		}
	}

}
